bitkeeper revision 1.1277.1.1 (425a8650v0vw6cLK5BguR8GpBzOj-A)
authordjm@djmnc4000.(none) <djm@djmnc4000.(none)>
Mon, 11 Apr 2005 14:14:40 +0000 (14:14 +0000)
committerdjm@djmnc4000.(none) <djm@djmnc4000.(none)>
Mon, 11 Apr 2005 14:14:40 +0000 (14:14 +0000)
Add domU restart capability.
Signed-off by: Dan Magenheimer (dan.magenheimer@hp.com)

xen/arch/ia64/domain.c
xen/arch/ia64/hypercall.c
xen/arch/ia64/process.c
xen/arch/ia64/xenmisc.c
xen/include/asm-ia64/config.h
xen/include/asm-ia64/domain.h

index 5a6d664087214279d7050d66fa49c3982f4bc4b9..d933f6704095fec6d47f25fc2dddfb9bc8c4fa99 100644 (file)
@@ -258,8 +258,8 @@ void new_thread(struct exec_domain *ed,
        sw->ar_pfs = 0;
        sw->ar_bspstore = new_rbs;
        //regs->r13 = (unsigned long) ed;
-printf("new_thread: ed=%p, regs=%p, sw=%p, new_rbs=%p, IA64_STK_OFFSET=%p, &r8=%p\n",
-ed,regs,sw,new_rbs,IA64_STK_OFFSET,&regs->r8);
+printf("new_thread: ed=%p, start_pc=%p, regs=%p, sw=%p, new_rbs=%p, IA64_STK_OFFSET=%p, &r8=%p\n",
+ed,start_pc,regs,sw,new_rbs,IA64_STK_OFFSET,&regs->r8);
        sw->b0 = (unsigned long) &ia64_ret_from_clone;
        ed->thread.ksp = (unsigned long) sw - 16;
        //ed->thread_info->flags = 0;
@@ -428,6 +428,7 @@ void loaddomainelfimage(struct domain *d, unsigned long image_start)
        int h, filesz, memsz, paddr;
        unsigned long elfaddr, dom_mpaddr, dom_imva;
        struct page *p;
+       unsigned long pteval;
   
        copy_memory(&ehdr,image_start,sizeof(Elf_Ehdr));
        for ( h = 0; h < ehdr.e_phnum; h++ ) {
@@ -456,9 +457,15 @@ void loaddomainelfimage(struct domain *d, unsigned long image_start)
        else
 #endif
        while (memsz > 0) {
+#ifdef DOMU_AUTO_RESTART
+               pteval = lookup_domain_mpa(d,dom_mpaddr);
+               if (pteval) dom_imva = __va(pteval & _PFN_MASK);
+               else { printf("loaddomainelfimage: BAD!\n"); while(1); }
+#else
                p = map_new_domain_page(d,dom_mpaddr);
                if (unlikely(!p)) BUG();
                dom_imva = __va(page_to_phys(p));
+#endif
                if (filesz > 0) {
                        if (filesz >= PAGE_SIZE)
                                copy_memory(dom_imva,elfaddr,PAGE_SIZE);
@@ -774,7 +781,9 @@ int construct_domU(struct domain *d,
        struct exec_domain *ed = d->exec_domain[0];
        unsigned long pkern_entry;
 
+#ifndef DOMU_AUTO_RESTART
        if ( test_bit(DF_CONSTRUCTED, &d->d_flags) ) BUG();
+#endif
 
        printk("*** LOADING DOMAIN %d ***\n",d->id);
 
@@ -808,7 +817,12 @@ int construct_domU(struct domain *d,
 
        set_bit(DF_CONSTRUCTED, &d->d_flags);
 
-       printk("calling new_thread\n");
+       printk("calling new_thread, entry=%p\n",pkern_entry);
+#ifdef DOMU_AUTO_RESTART
+       ed->domain->arch.image_start = image_start;
+       ed->domain->arch.image_len = image_len;
+       ed->domain->arch.entry = pkern_entry;
+#endif
        new_thread(ed, pkern_entry, 0, 0);
        printk("new_thread returns\n");
        __set_bit(0x30,ed->vcpu_info->arch.delivery_mask);
@@ -816,6 +830,17 @@ int construct_domU(struct domain *d,
        return 0;
 }
 
+#ifdef DOMU_AUTO_RESTART
+void reconstruct_domU(struct exec_domain *ed)
+{
+       /* re-copy the OS image to reset data values to original */
+       printk("reconstruct_domU: restarting domain %d...\n",
+               ed->domain->id);
+       loaddomainelfimage(ed->domain,ed->domain->arch.image_start);
+       new_thread(ed, ed->domain->arch.entry, 0, 0);
+}
+#endif
+
 // FIXME: When dom0 can construct domains, this goes away (or is rewritten)
 int launch_domainU(unsigned long size)
 {
index 7634e818dbc1133a0881b9b2b57b198937382c89..f568ee87b7209fddbda41ab24148629f7aa0eef9 100644 (file)
@@ -21,7 +21,7 @@ extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UI
 
 void fooefi(void) {}
 
-void
+int
 ia64_hypercall (struct pt_regs *regs)
 {
        struct exec_domain *ed = (struct domain *) current;
@@ -50,8 +50,15 @@ ia64_hypercall (struct pt_regs *regs)
                        printf("(by dom0)\n ");
                        (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
                }
+#ifdef DOMU_AUTO_RESTART
+               else {
+                       reconstruct_domU(current);
+                       return 0;  // don't increment ip!
+               }
+#else  
                printf("(not supported for non-0 domain)\n");
                regs->r8 = EFI_UNSUPPORTED;
+#endif
                break;
            case FW_HYPERCALL_EFI_GET_TIME:
                fooefi();
@@ -105,4 +112,5 @@ ia64_hypercall (struct pt_regs *regs)
                regs->r8 = domU_staging_read_8(vcpu_get_gr(ed,32));
                break;
        }
+       return 1;
 }
index 7e4b7947d18e82897c05754bf625fb11f714ebea..b88f5ea0c2e5523eac072613cdd18a97c1dafa7a 100644 (file)
@@ -714,8 +714,8 @@ ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, u
                else do_ssc(vcpu_get_gr(current,36), regs);
        }
        else if (iim == d->breakimm) {
-               ia64_hypercall(regs);
-               vcpu_increment_iip(current);
+               if (ia64_hypercall(regs))
+                       vcpu_increment_iip(current);
        }
        else reflect_interruption(ifa,isr,iim,regs,IA64_BREAK_VECTOR);
 }
index 8553335f91365d449df634c757a6c4d804615c69..5862544119257ac12d355c2b6fb9fcfd12f8349b 100644 (file)
@@ -276,6 +276,7 @@ void panic_domain(struct pt_regs *regs, const char *fmt, ...)
        extern spinlock_t console_lock;
        unsigned long flags;
     
+loop:
        printf("$$$$$ PANIC in domain %d (k6=%p): ",
                ed->domain->id, ia64_get_kr(IA64_KR_CURRENT));
        va_start(args, fmt);
@@ -285,5 +286,11 @@ void panic_domain(struct pt_regs *regs, const char *fmt, ...)
        if (regs) show_registers(regs);
        domain_pause_by_systemcontroller(current->domain);
        set_bit(DF_CRASHED, ed->domain->d_flags);
-       //while(test);
+       if (ed->domain->id == 0) {
+               int i = 1000000000L;
+               // if domain0 crashes, just periodically print out panic
+               // message to make post-mortem easier
+               while(i--);
+               goto loop;
+       }
 }
index 473d3f2c66e5cfceedc0b034eb44c1b5b39ee4b5..7216d02157df6ded724d779a6731d86743a778ca 100644 (file)
@@ -1,8 +1,9 @@
 // control flags for turning on/off features under test
 #undef CLONE_DOMAIN0
-//#define CLONE_DOMAIN0 5
+//#define CLONE_DOMAIN0 1
 #define DOMU_BUILD_STAGING
 #define VHPT_GLOBAL
+#define DOMU_AUTO_RESTART
 
 // manufactured from component pieces
 
index 9d81680d2034f25782e958fad598c79bf18b8e9f..7a5d1166a376b5b92786c4e9eff8fd15f403aafb 100644 (file)
@@ -21,6 +21,11 @@ struct arch_domain {
     u64 xen_vastart;
     u64 xen_vaend;
     u64 shared_info_va;
+#ifdef DOMU_AUTO_RESTART
+    u64 image_start;
+    u64 image_len;
+    u64 entry;
+#endif
 };
 #define metaphysical_rid arch.metaphysical_rid
 #define starting_rid arch.starting_rid